/**
 * Copyright (c) 2006-2013 Las Venturas Mineground
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program.
 * If not, see <http://www.gnu.org/licenses/>.
 */

package org.mineground;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

import org.mineground.features.communication.AdministratorChat;

/**
 * The feature controller owns all features in the Mineground plugin. Each of the features will be
 * initialized as needed by the constructor, for example if they need access to the database
 * connection. Features *may* access each other, and their constructors will be given access to
 * this instance of the controller allowing them to do so.
 */
public class FeatureController {
    private final Map<String, Feature> mFeatureMap = new HashMap<String, Feature>();
    
    /**
     * Initializes all Mineground features, optionally passing along shared features such as the
     * database connection of the plugin's configuration. Please read the comment at the beginning
     * of this method for what information may be passed to any feature in Mineground.
     * 
     * @param databaseConnection The Database Connection handler allowing access to MySQL.
     */
    public FeatureController(Object databaseConnection) {
        // Add new features in alphabetical order. Only the following variables may be passed to
        // the constructors of said features, and only in the order they're listed here.
        //
        // this               - Instance of the FeatureController, if they need to get access to
        //                      other features through the FeatureController::get() method.
        // databaseConnection - Instance of the database connection being used for Mineground. Only
        //                      if the feature needs to access the MySQL database.

        RegisterFeature("AdministratorChat", new AdministratorChat());
    }
    
    /**
     * Allows features to get weak references to instances of other features. This method returns a
     * weak reference to the feature's instance if it can be found, or NULL if no feature with the
     * given name exists. Users of this method should not store the instance of the feature, but
     * instead the weak reference returned by this method.
     * 
     * @param name Name of the feature which you'd like to get a reference to.
     * @return A weak reference to the feature with the specified name, or null.
     */
    public WeakReference<Feature> get(String name) {
        Feature feature = mFeatureMap.get(name);
        if (feature == null)
            return null;
        
        return new WeakReference<Feature>(feature);
    }
    
    /**
     * Registers a feature in the feature map we maintain, allowing other features to get access to
     * it by invoking FeatureController::get(). This method mostly exists for readability.
     * 
     * @param name Name of the feature that's being registered.
     * @param instance Instance of the feature's base class, which should implement Feature.
     */
    private void RegisterFeature(String name, Feature instance) {
        mFeatureMap.put(name, instance);
    }
}
